using Senparc.Weixin.Exceptions;
using Senparc.Weixin.MP.Entities;
using Senparc.Weixin.MP.Entities.Request;
using Senparc.Weixin.MP.Helpers;
using System;
using System.IO;
using System.Xml;
using System.Xml.Linq;
namespace Senparc.Weixin.MP
{
	public static class RequestMessageFactory
	{
		public static IRequestMessageBase GetRequestEntity(XDocument doc, PostModel postModel = null)
		{
			RequestMessageBase requestMessageBase = null;
			try
			{
				RequestMsgType requestMsgType = MsgTypeHelper.GetRequestMsgType(doc);
				switch (requestMsgType)
				{
				case RequestMsgType.Text:
					requestMessageBase = new RequestMessageText();
					break;
				case RequestMsgType.Location:
					requestMessageBase = new RequestMessageLocation();
					break;
				case RequestMsgType.Image:
					requestMessageBase = new RequestMessageImage();
					break;
				case RequestMsgType.Voice:
					requestMessageBase = new RequestMessageVoice();
					break;
				case RequestMsgType.Video:
					requestMessageBase = new RequestMessageVideo();
					break;
				case RequestMsgType.Link:
					requestMessageBase = new RequestMessageLink();
					break;
				case RequestMsgType.ShortVideo:
					requestMessageBase = new RequestMessageShortVideo();
					break;
				case RequestMsgType.Event:
				{
					string text = doc.Root.Element("Event").Value.ToUpper();
					switch (text)
					{
					case "ENTER":
						requestMessageBase = new RequestMessageEvent_Enter();
						goto IL_404;
					case "LOCATION":
						requestMessageBase = new RequestMessageEvent_Location();
						goto IL_404;
					case "SUBSCRIBE":
						requestMessageBase = new RequestMessageEvent_Subscribe();
						goto IL_404;
					case "UNSUBSCRIBE":
						requestMessageBase = new RequestMessageEvent_Unsubscribe();
						goto IL_404;
					case "CLICK":
						requestMessageBase = new RequestMessageEvent_Click();
						goto IL_404;
					case "SCAN":
						requestMessageBase = new RequestMessageEvent_Scan();
						goto IL_404;
					case "VIEW":
						requestMessageBase = new RequestMessageEvent_View();
						goto IL_404;
					case "MASSSENDJOBFINISH":
						requestMessageBase = new RequestMessageEvent_MassSendJobFinish();
						goto IL_404;
					case "TEMPLATESENDJOBFINISH":
						requestMessageBase = new RequestMessageEvent_TemplateSendJobFinish();
						goto IL_404;
					case "SCANCODE_PUSH":
						requestMessageBase = new RequestMessageEvent_Scancode_Push();
						goto IL_404;
					case "SCANCODE_WAITMSG":
						requestMessageBase = new RequestMessageEvent_Scancode_Waitmsg();
						goto IL_404;
					case "PIC_SYSPHOTO":
						requestMessageBase = new RequestMessageEvent_Pic_Sysphoto();
						goto IL_404;
					case "PIC_PHOTO_OR_ALBUM":
						requestMessageBase = new RequestMessageEvent_Pic_Photo_Or_Album();
						goto IL_404;
					case "PIC_WEIXIN":
						requestMessageBase = new RequestMessageEvent_Pic_Weixin();
						goto IL_404;
					case "LOCATION_SELECT":
						requestMessageBase = new RequestMessageEvent_Location_Select();
						goto IL_404;
					case "CARD_PASS_CHECK":
						requestMessageBase = new RequestMessageEvent_Card_Pass_Check();
						goto IL_404;
					case "CARD_NOT_PASS_CHECK":
						requestMessageBase = new RequestMessageEvent_Card_Not_Pass_Check();
						goto IL_404;
					case "USER_CARD":
						requestMessageBase = new RequestMessageEvent_User_Card();
						goto IL_404;
					case "USER_DEL_CARD":
						requestMessageBase = new RequestMessageEvent_User_Del_Card();
						goto IL_404;
					case "KF_CREATE_SESSION":
						requestMessageBase = new RequestMessageEvent_Kf_Create_Session();
						goto IL_404;
					case "KF_CLOSE_SESSION":
						requestMessageBase = new RequestMessageEvent_Kf_Close_Session();
						goto IL_404;
					case "KF_SWITCH_SESSION":
						requestMessageBase = new RequestMessageEvent_Kf_Switch_Session();
						goto IL_404;
					case "POI_CHECK_NOTIFY":
						requestMessageBase = new RequestMessageEvent_Poi_Check_Notify();
						goto IL_404;
					case "WIFICONNECTED":
						requestMessageBase = new RequestMessageEvent_WifiConnected();
						goto IL_404;
					case "USER_CONSUME_CARD":
						requestMessageBase = new RequestMessageEvent_User_Consume_Card();
						goto IL_404;
					case "USER_ENTER_SESSION_FROM_CARD":
						requestMessageBase = new RequestMessageEvent_User_Enter_Session_From_Card();
						goto IL_404;
					case "USER_VIEW_CARD":
						requestMessageBase = new RequestMessageEvent_User_View_Card();
						goto IL_404;
					case "MERCHANT_ORDER":
						requestMessageBase = new RequestMessageEvent_Merchant_Order();
						goto IL_404;
					case "SUBMIT_MEMBERCARD_USER_INFO":
						requestMessageBase = new RequestMessageEvent_Submit_Membercard_User_Info();
						goto IL_404;
					case "SHAKEAROUNDUSERSHAKE":
						requestMessageBase = new RequestMessageEvent_ShakearoundUserShake();
						goto IL_404;
					}
					requestMessageBase = new RequestMessageEventBase();
					IL_404:
					break;
				}
				default:
					throw new UnknownRequestMsgTypeException(string.Format("MsgType：{0} 在RequestMessageFactory中没有对应的处理程序！", requestMsgType), new ArgumentOutOfRangeException());
				}
				//requestMessageBase.FillEntityWithXml(doc);
			}
			catch (ArgumentException inner)
			{
				throw new WeixinException(string.Format("RequestMessage转换出错！可能是MsgType不存在！，XML：{0}", doc.ToString()), inner);
			}
			return requestMessageBase;
		}
		public static IRequestMessageBase GetRequestEntity(string xml)
		{
			return RequestMessageFactory.GetRequestEntity(XDocument.Parse(xml), null);
		}
		public static IRequestMessageBase GetRequestEntity(Stream stream)
		{
			IRequestMessageBase requestEntity;
			using (XmlReader xmlReader = XmlReader.Create(stream))
			{
				XDocument doc = XDocument.Load(xmlReader);
				requestEntity = RequestMessageFactory.GetRequestEntity(doc, null);
			}
			return requestEntity;
		}
	}
}
